package com.sh.d1.gatewayserver.router;

import com.sh.d1.gameserver.msg.GameMsgProtocol;
import com.sh.d1.gatewayserver.GatewayServer;
import com.sh.d1.gatewayserver.IdSetterGetter;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 路由器
 */
public class RouterHandler  extends ChannelInboundHandlerAdapter {

    static private final Logger LOGGER = LoggerFactory.getLogger(RouterHandler.class);

    private final LoginMsgHandler _loginMsgHandler=new LoginMsgHandler();
    private final GameMsgHandler   _gameMsgHandler=new GameMsgHandler();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msgObj) throws Exception {
        LOGGER.info(
                "收到客户端数据, msgType = {}",
                msgObj.getClass().getName()
        );

        if (!(msgObj instanceof BinaryWebSocketFrame)) {
            return;
        }

        // 网关服务器 Id
        int gatewayServerId = Integer.parseInt(GatewayServer.getId());
        // 获取会话 Id
        int sessionId = IdSetterGetter.getSessionId(ctx.channel());
        // 来自用户 Id
        int fromUserId = IdSetterGetter.getUserId(ctx.channel());

        BinaryWebSocketFrame inputFrame = (BinaryWebSocketFrame) msgObj;

        ByteBuf oldByteBuf = inputFrame.content();
        ByteBuf newByteBuf = ctx.alloc().buffer();

        // 先读掉原来的消息长度
        oldByteBuf.readShort();
        //读取消息编号
        int msgCode = oldByteBuf.readShort();

        // 写出消息长度
        newByteBuf.writeShort(0); // 写出消息长度, 临时用 0 来占位


        // 写出网关服务器 Id 和会话 Id
        newByteBuf.writeInt(gatewayServerId);
        newByteBuf.writeInt(sessionId);
        // 写出来自用户 Id
        newByteBuf.writeInt(fromUserId);
        //写出消息编号
        newByteBuf.writeShort(msgCode);
        // 将剩余的字节填充到新 Buf 中
        oldByteBuf.readBytes(newByteBuf, oldByteBuf.readableBytes());

        // 写出消息真实长度
        newByteBuf.setShort(0, newByteBuf.readableBytes() - 2);

        BinaryWebSocketFrame outputFrame = new BinaryWebSocketFrame(newByteBuf);

        LOGGER.info(
                "将消息转发到 gameServer, sessionId = {},userId = {},msgCode = {}",
                sessionId,
                fromUserId,
                msgCode
        );

        if (GameMsgProtocol.MsgCode.USER_LOGIN_CMD_VALUE== msgCode) {
            _loginMsgHandler.sendMsg(ctx, outputFrame);
        } else {
            _gameMsgHandler.sendMsg(ctx, outputFrame);
        }
    }
}
